#include <iostream>
#include "fpdfview.h"
#include "fpdf_edit.h"
#include "fpdf_text.h"
#include "fpdf_save.h"
#include<QDebug>
#include"fpdf_edit.h"
#include "turbojpeg.h"
static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) {
    // 打开文件
    FILE* outFile = fopen("output.pdf", "ab"); // 以二进制写入模式打开文件
    if (!outFile) {
        // 文件打开失败
        // 释放内存
        return -1;
    }else{
        printf("open successful");
    }
    // 将缓冲区中的数据写入文件
    size_t bytesWritten = fwrite(buffer, 1, size, outFile);
    if (bytesWritten != size) {
        // 写入失败
        fclose(outFile); // 关闭文件
        return -1;
    }
    // 关闭文件
    fclose(outFile);
    return 1;
}
/*写内存到文件*/
void write_buffer2file(char *filename, uchar *buffer, int size)
{
    FILE *fd = fopen(filename,"wb");
    if (NULL == fd) {
        return;
    }
    fwrite(buffer,1,size,fd);
    fclose(fd);
}
static int MyGetBlock(void* param, unsigned long position, unsigned char* pBuf, unsigned long size) {
    const char* file_path = static_cast<const char*>(param);
    FILE *fd = fopen(file_path, "rb");
    if(fd == NULL){
        qDebug() << "open error";
        return 0;
    }
    if(fseek(fd, position, SEEK_SET) != 0){
        qDebug() << "seek error";
        fclose(fd);
        return 0;
    }
    size_t bytesRead = fread(pBuf, 1, size, fd);
    if (bytesRead != size) {
        qDebug() << "read error";
        fclose(fd);
        return 0; // 错误，读取数据失败
    }
    qDebug() << "successful" << std::strlen((char*)pBuf);
    fclose(fd);
    return 1; //成功
}
int main() {
    // 打开 PDF 文件
    FPDF_InitLibrary();
        tjhandle handle= tjInitCompress();
        tjhandle handle1= tjInitDecompress();
    FPDF_DOCUMENT pdf_doc = FPDF_LoadDocument("test.pdf", nullptr);
    if (!pdf_doc) {
        std::cerr << "Failed to open PDF file!" << std::endl;
        return 1;
    }
    int num_pages = FPDF_GetPageCount(pdf_doc);
    // 遍历每一页
    for (int i = 0; i < num_pages; ++i) {
        FPDF_PAGE page = FPDF_LoadPage(pdf_doc, i);
        double page_width = FPDF_GetPageWidthF(page);
        double page_height = FPDF_GetPageHeightF(page);
        if (!page) {
            std::cerr << "Failed to load page " << i << std::endl;
            continue;
        }
        // qDebug()<<FPDFPage_HasTransparency(page);
        // 获取页面对象数量
        int num_objs = FPDFPage_CountObjects(page);
        // 遍历页面对象
        for (int j = num_objs - 1; j >= 0; --j) {
            FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, j);
            if (!obj) {
                std::cerr << "Failed to get object " << j << " on page " << i << std::endl;
                continue;
            }
            // qDebug()<<"obj"<<FPDFPageObj_HasTransparency(obj);
            unsigned int R,G,B,A;
            FPDFPageObj_GetFillColor(obj,&R,&G,&B,&A);
            // qDebug()<<"R"<<R<<"G"<<G<<"B"<<B<<"A"<<A;
            // 检查对象类型是否为图片
            if (FPDFPageObj_GetType(obj) == FPDF_PAGEOBJ_IMAGE) {
                FPDF_BITMAP bitmap=FPDFImageObj_GetBitmap(obj);
                void *buffer=FPDFBitmap_GetBuffer(bitmap);
                unsigned long bufferLen=strlen((char*)buffer);
                qDebug()<<"before compress buffer size:"<<bufferLen;
                if(bufferLen==0){
                    FPDFPage_RemoveObject(page,obj);
                }
                // FPDFImageObj_GetImageDataDecoded(obj,buffer,65536);
                int width=FPDFBitmap_GetWidth(bitmap);
                int height=FPDFBitmap_GetHeight(bitmap);
                uchar *outjpg_buf=NULL;
                unsigned long outjpg_size;
                int pixelfmt = TJPF_BGR;
                int subsamp = TJSAMP_422;
                FPDF_FILEACCESS fileAccess;
                qDebug()<<"compress"<<tjCompress2(handle,(uchar*)buffer,width,0,height,pixelfmt,&outjpg_buf,&outjpg_size,subsamp,10,0);
                char filename[]="file";
                write_buffer2file(filename,outjpg_buf,outjpg_size);
                qDebug()<<"compressing buffer size:"<<strlen((char*)outjpg_buf)<<"outjpeg_size"<<outjpg_size;
                fileAccess.m_FileLen=outjpg_size;
                fileAccess.m_Param=filename;
                fileAccess.m_GetBlock=&MyGetBlock;
                if(outjpg_size<bufferLen){
                    //两种方法 第一种从之前保存的文件中读取。
                FPDFImageObj_LoadJpegFileInline(&page,0,obj,&fileAccess);
                    //第二种 解压缩 设置到bitmap里 第一种压缩率要大
                // qDebug()<<"decompress"<<tjDecompress2(handle1,outjpg_buf,outjpg_size,(uchar*)buffer,width,0,height,pixelfmt,0);
                // bufferLen=strlen((char*)buffer);
                // qDebug()<<"after compress buffer size:"<<bufferLen;
                }
                // FPDF_BITMAP bitmap1=FPDFBitmap_CreateEx(width,height,2,buffer,0);
                // FPDFImageObj_SetBitmap(&page,0,obj,bitmap1);
                FPDFBitmap_Destroy(bitmap);
                // FPDFBitmap_Destroy(bitmap1);
            }
            else if(FPDFPageObj_GetType(obj) == FPDF_PAGEOBJ_TEXT){
                FPDF_TEXTPAGE textPage=FPDFText_LoadPage(page);
                FPDF_WCHAR content_buffer[256];
                unsigned long len=FPDFTextObj_GetText(obj,textPage,content_buffer,100);
                QString content=QString::fromWCharArray(reinterpret_cast<const wchar_t*>(content_buffer));
                // qDebug() << "Text content: " << content<<" len:"<<len<<" mode:"<<FPDFTextObj_GetTextRenderMode(obj);
                if(FPDFTextObj_GetTextRenderMode(obj)==FPDF_TEXTRENDERMODE_INVISIBLE ||len==2){
                    FPDFPage_RemoveObject(page,obj);
                }
            }
            else if(FPDFPageObj_GetType(obj)==FPDF_PAGEOBJ_FORM){

            }
            else if(FPDFPageObj_GetType(obj)==FPDF_PAGEOBJ_PATH){

            }
            else if(FPDFPageObj_GetType(obj)==FPDF_PAGEOBJ_SHADING){

            }
            else if(FPDFPageObj_GetType(obj)==FPDF_PAGEOBJ_UNKNOWN){
                FPDFPage_RemoveObject(page,obj);
            }
            FPDFPageObj_SetFillColor(obj,R,B,G,A);
        }
        FPDFPage_GenerateContent(page);

        FPDF_ClosePage(page);
    }
    // 保存修改后的 PDF
    // FPDF_SaveAsCopy(pdf_doc, "output_pdf_file.pdf",FPDF_NO_INCREMENTAL);
        FPDF_FILEWRITE fileWrite;
        fileWrite.version=0;
        fileWrite.WriteBlock=&writeBlock;
        FPDF_SaveAsCopy(pdf_doc,&fileWrite,FPDF_NO_INCREMENTAL);
    FPDF_CloseDocument(pdf_doc);
    FPDF_DestroyLibrary();
    return 0;
}
